#include "../../include/online/LRUCache.hpp"
#include "../../include/online/Thread.hpp"
#include "../../include/server/Logger.hpp"
#include <iostream>
#include <fstream>
#include <sstream>

using std::cout;
using std::endl;
using std::ifstream;
using std::istringstream;
using std::ofstream;

/*extern*/  __thread size_t __thread_id;

LRUCache::LRUCache(size_t capacity)
: _capacity(capacity){

}

//查询缓存是否命中
bool LRUCache::isHit(const string &query) {
    return _hashMap.count(query) > 0;
}

//获取记录
string LRUCache::getRecord(const string &query) {
    //未命中
    if (!isHit(query))
        return "";
    //命中
    cout << "No. " << __thread_id <<  " cache is hit" << endl;
    //最近访问的记录移到头部
    _resultList.splice(_resultList.begin(), _resultList, _hashMap[query]);
    //返回查询的key对应的value
    return _hashMap[query]->second;
}

void LRUCache::insertRecord(const string &query, const string &result) {
    if(isHit(query)){
        //记录移动到头部
        _resultList.splice(_resultList.begin(), _resultList, _hashMap[query]);
    } else {
        //更新结果插入Cache头部
        _resultList.push_front({query, result});
        //更新迭代器的索引信息
        _hashMap[query] = _resultList.begin();
        //判断缓存是否已满
        if(_resultList.size() > _capacity) {
            auto back_key = _resultList.back().first;
            _resultList.pop_back();
            _hashMap.erase(back_key);
        }
    }
}

void LRUCache::clear() {
    _resultList.clear();
    _hashMap.clear();
}

void LRUCache::update(const LRUCache &cache) {
    //更新缓存，最后的缓存先更新
    for(auto it = cache._resultList.rbegin(); it != cache._resultList.rend(); ++it) {
        insertRecord(it->first, it->second);
    }
}

size_t LRUCache::size() const {
    return _resultList.size();
}
